########################################################
#   Description of Scene mode in Little Grid Builder   #
########################################################

 Scene mode is special feature that allows third-party programs to send commands to Builder making it to display some typical scene elements, such as flags, zones and actors.

 IMPORTANT: The method of communication has changed since version 0.07! Previous communication method is not supported any more! Please read this document to know how to use the new scene mode communication.
 
 Since version 0.08 "flags" are called "tracks" in this document.

First you have to run the Builder program with special parameters, for example:

C:\LBArchitect\Builder.exe scenemode x y

Where x is the Lba version (1 or 2), and y is the room index (starting with 1).
For example: "C:\LBArchitect\Builder.exe scenemode 1 4" will cause running the program (if it's located in C:\LBArchitect directory) and automatical opening room 4 from Lba 1 (if all necessary files are set in configuration).

 What to do first:
-------------------

To communicate with the program you have to send messages to the program.
Firs you have to obtain handle of the Builder window. You can do it by calling the FindWindow() Win API function. For example:

(Delphi)
var BuilderHandle: HWND;
begin
 BuilderHandle := FindWindow(nil,'Little Grid Builder - Scene Mode');
end;

(C++)
{
 void *BuilderHandle;
 BuilderHandle = FindWindow(0,"Little Grid Builder - Scene Mode");
}

First parameter specifies the class name of the window, and it is not necessary. Second parameter specifies the name of the window we are looking for.

After that opration you know the handle to the Builder window, and you can send some messages to it. You can look for the handle once, when the program start, or every time you want to send something. In the second case you will know if something will go wrong (e.g. someone close the Builder window) before you send a message. Otherwise nothing wrong will happen, the message will return 0 indicating that it has not been sent.


 Communication - what you can do next:
---------------------------------------

 To be able to send something you have to define the format in which it will be sent. This format is as follows:

(Delphi)
type
 TComData = record
  Id: Byte;
  x1, y1, z1, x2, y2, z2: SmallInt; //signed 16-bit integer
  Data: Integer;
  Text: array[0..200] of Char; //200 chars + #0
  cx1, cy1, cx2, cy2: SmallInt;
 end;

(C++)
typedef struct
{
 byte Id;
 short x1, y1, z1, x2, y2, z2;
 int Data;
 char Text[201];  //200 chars + '\0'
 short cx1, cy1, cx2, cy2;
} TComData;

Meaning of the fields:
 - Id value contains index of object to be created or deleted. This variable can be any value between 0 and 255.
 - x1, y1, z1, x2, y2, z2 - coordinates of the new object.
 - Data - value providing an additional information, used in some commands.
 - Text - description of new object. It must be null-terminated string with maximum 200 characters (plus one for the trailing null (0x00) character).
 - cx1, cy1, cx2, cy2 - clipping coordinates of specified actor.

 You can define this structure as type or as a variable, it's your choice. But remember, that you have to declare at least one GLOBAL variable of the type above, because the data must be "present" during sending.

 Communication between the programs is provided through Windows message WM_COPYDATA. To send that message to another program you have to use SendMessage() function. It requires to define an additional variable of type TCopyDataStruct, which then will hold a pointer to the actual TComData structure. Example:

(Delphi)
var
 BuilderHandle: HWND;
 DataStruct: TCopyDataStruct;
 ComData: TComData;
 MsgResult: Integer;
begin
 DataStruct.dwData:= 01;
 DataStruct.cbData:= SizeOf(TComData);
 DataStruct.lpData:= @ComData;
 MsgResult:= SendMessage(BuilderHandle, WM_COPYDATA, 0, Integer(@DataStruct));
end;

(C++)
{
 void *BuilderHandle;
 TCopyDataStruct DataStruct;
 TComData ComData;
 int MsgResult;
 DataStruct.dwData = 01;
 DataStruct.cbData = sizeof(TComData);
 DataStruct.lpData = &ComData;
 MsgResult = SendMessage(BuilderHandle, WM_COPYDATA, 0, (int)&DataStruct);
}

 You must have two structure variables declared. First the variable of type TComData, which will contain the actual information you are going to send to the Builder. Second is the variable of type TCopyDataStruct, which will contain pointer to the ComData variable and some additional information. This structure type is already defined in one of the C++ standard libraries, and there is no need to do it by yourself. Third variable is integer that will contain the resulting value of the SendMessage() function.

 The TCopyDataStruct structure contains three fields:
  dwData - contains user data to be passed through the message, and it is used to pass the command code. Command codes are described later in this file.
  cbData - contains size (in bytes) of the TComData structure. It is always the same, however it is more safe, to use the function sizeof() to obtain it.
  lpData - contains pointer to your ComData variable. Remember, that the ComData must be a global variable!

 SendMessage() function requires four parameters:
  BuilderHandle - is a handle of the window that the message is going to be passed to; the method of obtaining it has been described earlier in this file
  WM_COPYDATA - is a constant
  0 - is the wParam parameter, and should be always zero
  (int)&DataStruct - is the pointer to the DataStruct variable typecasted as an integer (because an integer has to be passed as this parameter not a pointer).

 SendMessage() will not return until the message has been processed. When the message is processed the function will return a value depending on the message. Possible return values are listed later in this file.


 Command codes (all values are decimal):
-----------------------------------------
 01 - test
 02 - open another grid
 03 - close program (deprecated)
 04 - enable backward communication
 08 - begin updating
 09 - end updating
 11 - set Track
 12 - delete Track
 13 - delete all Tracks
 14 - select Track
 21 - set Zone
 22 - delete Zone
 23 - delete all Zones
 24 - select Zone (not working in version 0.08)
 31 - set Actor
 32 - delete Actor
 33 - delete all Actors
 34 - select Actor

 Meaning:

 01 - Test command. This command can be used for testing. After receiving this command the program will return value of 1000 (instead of 999 for a normal command). All parameters are ignored, but checking if the parameter structure has valid format is performed. Note that for the next commands unused parameters (unused by that command) will not be described.

 02 - Open another Grid. This command will cause the program to close the current grid and open another one given by parameters. Paramaters: Id - specifies the Lba version (1 or 2); Data - specifies the new room index (starting with 1);

 03 - Close program. This command will immediately close the LBArchitect.
 IMPORTANT: Due to some problems with this command, it is deprecated since version 0.08 and it will be removed in future versions. Instead of this command please use WM_CLOSE message instead of WM_COPYDATA. For example: SendMessage(BuilderHandle, WM_CLOSE, 0, 0);. When sending this message you should not check it's return value, as you might have been doing for WM_COPYDATA message.

 04 - Enable Backward Communication. This command will tell Builder that the third-party program sending this command is also able to receive commands. It will enable such features as "visual" editing, creating and deleting scene elements. Parameters: Data - handle of the window of the program sending the command, Builder will send backward commands to the window specified by this handle. If the handle of the window is changed at run-time, you should snd this command again, to inform Builder about that fact. More information about backward communication you will find in Backward Communication section of this file.

 08 - Begin updating. Send this command to indicate that several Tracks, Zones or Actors will be updated at once. This will make the program not refresh the screen during the updates, thus significantly increasing the commuication speed.

 09 - End updating. Send this command to indicate that update has been done. This will cause full screen refresh, and further single element updates will be processed with necessary screen updates.

 11 - Set Track. This command will add new Track at index given by Id parameter into the Track array. If a Track at this index already exists, it will be replaced. Parameters: Id - index of the Track to be created; x1, y1, z1 - scene coordinates of the new Track; Text - caption of the Track.

 12 - Delete Track. This command will delete Track at index given by Id parameter, so that it will not be visible any more.

 13 - Delete all Tracks. This command will delete all Tracks, that have been set. It is optimized to be much faster than deleting Tracks one by one.

 14 - Select Track. This command will draw a rectangle around Track with index given by its Id parameter, indincating that it is selected.

 21 - Set Zone. This command will add new Zone at index given by Id parameter into the Zone array. If a Zone at this index already exists, it will be replaced. Parameters: Id - index of the Zone to be created; x1, y1, z1, x2, y2, z2 - scene coordinates of the new Zone; Text - caption of the Zone; Data - integer value indicating type of the new Zone.

 22 - Delete Zone. This command will delete zone at index given by Id parameter, so that it will not be visible any more.

 23 - Delete all Zones. This command will delete all Zones, that have been set. It is optimized to be much faster than deleting Zones one by one.

 44 - Select Zone. This command will draw a rectangle around Zone with index given by its Id parameter, indincating that it is selected. This command is not working yet in version 0.08.

 31 - Set Actor. This command will add new Actor at index given by Id parameter into the Actor array. If an Actor at this index already exists, it will be replaced. Parameters: Id - index of the Actor to be created; x1, y1, z1 - scene coordinates of the new Actor; Text - caption of the Actor; data - sprite index if the Actor is sprite Actor, if the Actor is normal Actor the value should be 0; cx1, cy1, cx2, cy2 - clipping coordinates for the Actor (if the Actor doesn't use clipping, set these parameters to 0).

 32 - Delete Actor. This command will delete Actor at index given by Id parameter, so that it will not be visible any more.

 33 - Delete all Actors. This command will delete all Actors, that have been set. It is optimized to be much faster than deleting Actors one by one.
 
 34 - Select Actor. This command will draw a rectangle around Actor with index given by its Id parameter, indincating that it is selected.


 Return values:
----------------

SendMessage() function will return one of the following values:

 0 - Error: Unknown error (probably the program has not even received the message).
 1 - Error: Not in Scene Mode - this code indicates that program is in normal editing mode, not in scene mode. It may happen if the program has beed opened without "scenemode" parameter or if it didn't switched into scene mode for some reason (quite impossible).
 2 - Error: Unknown command - the command send through the message has unknown code.
 3 - Error: Invalid data format - pointer to the command structure passed by the message is not valid. The program only checks if the pointer reived from the message is not "access violation", so it may return "status ok" even if the structure is not exactly correct, but pointer is assigned.
 4 - Error: invalid parameters - one or more parameters passed through the command are invalid (for example if you send command 02 (open another grid) with parameter Id = 3.
 999 - Everything is OK - command has been received and processed.
 1000 - Communication test OK. Return value for communication testing command (01).


 Examples:
-----------
 The following are example codes of sending a command to create new Track at coordinates [1000,500,2000], and with caption "Track 1". The Id of the Track will be 10. Note that some language statement elements have been skipped.

(Delphi)
type
 TComData = record
  Id: Byte;
  x1, y1, z1, x2, y2, z2: SmallInt;
  Data: Integer;
  Text: array[0..200] of Char;
 end;

var
 BuilderHandle: HWND;
 DataStruct: TCopyDataStruct;
 ComData: TComData;
 MsgResult: Integer;

begin
 BuilderHandle:= FindWindow(nil, 'Little Grid Builder - Scene Mode');

 ComData.Id:= 10;
 ComData.x1:= 1000;
 ComData.y1:= 500;
 ComData.z1:= 2000;
 //remaining cooordinates are not used by the command we want to send,
 //so we can skip them
 StrPCopy(ComData.Text, 'Track 1'); //convert ansi string to null-terminated string

 DataStruct.dwData:= 11;                //command code
 DataStruct.cbData:= SizeOf(TComData);
 DataStruct.lpData:= @ComData;
 MsgResult:= SendMessage(BuilderHandle, WM_COPYDATA, 0, Integer(@DataStruct));
 //now we have in the MsgResult value returned by the Builder,
 //and we can check whether or not the message has been processed correctly
end;

(C++)
typedef struct
{
 byte Id;
 short x1, y1, z1, x2, y2, z2;
 int Data;
 char Text[201];
}
TComData;

{
 void *BuilderHandle;
 TCopyDataStruct DataStruct;
 TComData ComData;
 int MsgResult;

 BuilderHandle = FindWindow(0, "Little Grid Builder - Scene Mode");

 ComData.Id = 10;
 ComData.x1 = 1000;
 ComData.y1 = 500;
 ComData.z1 = 2000;
 //remaining cooordinates are not used by the command we want to send,
 //so we can skip them
 strcpy(ComData.Text, "Track 1"); //convert ansi string to null-terminated string

 DataStruct.dwData = 01;
 DataStruct.cbData = sizeof(TComData);
 DataStruct.lpData = &ComData;
 MsgResult = SendMessage(BuilderHandle, WM_COPYDATA, 0, (int)&DataStruct);
}



#############################################################
#   Backward Communication - how to enjoy editing scenes:   #
#############################################################

 Backward Communication allows other programs (scene editors), that use Scene Mode to display scene elements in Builder, to be informed about changes users make in the Builder window moving scene elements with mouse, adding and deleting them.

 Backward Communication works in the same way as normal communication in Scene Mode, with one difference, that in this case Builder sends commands, and the scene editor receive them. The way of backward communication is the same as of normal communication - commands are sent through the WM_COPYDATA message. For information how to make your program able to receive the WM_COPYDATA message refer to programming language manuals suitable for the programming language in which your program is written.
 Backward communication, like normal communication uses data structure to send information. The structure is similar to the normal communication structure, but it is NOT THE SAME. The structure should be defined as following:

(Delphi)
TBackCommand = record
 Id: Byte;
 x1, y1, z1, x2, y2, z2: SmallInt;
end;

(C++)
typedef struct
{
 byte Id;
 short x1, y1, z1, x2, y2, z2;
} TBackCommand;

Where:
 Id - is index of the object to edit/create/delete.
 x1, y1, z1, x2, y2, z2 - are new coordinates of the object.


 Where to start:
-----------------

 A program may enable Backward Communication by sending Command 04 with Data parameter containing handle of its window that will receive backward commands. Until Backward Communication is enabled, all editing features in Builder (Scene Mode) will be disabled.

 After receiving the Enable Backward Communcation command (04) Builder will test the backward communication by sending backward command 01 and checking if response is equal to 1000. Below there are descriptions of all backward commands that are supported by Builder.


 Backward Command codes (decimal):
-----------------------------------
 01 - test
 10 - Set Tracks coordinates
 11 - Select Track
 12 - Delete Track
 13 - New Track
 20 - Set Zones coordinates
 21 - Select Zone
 22 - Delete Zone
 23 - New Zone
 24 - Clone Zone (all parameters)
 29 - New zone (all parameters)
 30 - Set Actors coordinates
 31 - Select Actor
 32 - Delete Actor
 33 - New Actor
 35 - Clone Actor

 Meaning:

 01 - Test Command. This backward command is used for testing. After receiving this backward command the scene editor should return value of 1000 (instead of 100 for a normal backward command). All parameters should be ignored.

 10 - Set Track coordinates. This backward command will move Track with index specified by Id to new coordinates specified by [x1, y1, z1, x2, y2 ,z2].

 11 - Select Track. This backward command will indicate that Track with index specified by Id has just been selected. The scene editor can react to this by highlighting that Track, or by showing the Track's parameters.

 12 - Delete Track. This backward command will delete Track with index given by Id. After deleting the Track scene editor should send normal commands to delete all tracks, and send them again to ensure the Track indexes are consistent between Builder and the scene editor.

 13 - New Track. This backward command will create a new Track with index equal to the largest Track index in the scene plus one. Scene Editor should send the new Track's parameters back to Builder (command 11 - Set Track).

 20 - Set Zone coordinates. This backward command will move Zone with index specified by Id to new coordinates specified by [x1, y1, z1, x2, y2 ,z2]. It is not working yet in version 0.08 (Builder will never send this backward command).

 21 - Select Zone. This backward command will indicate that Zone with index specified by Id has just been selected. The scene editor can react to this by highlighting that Zone, or by showing the Zone's parameters. It is not working yet in version 0.08 (Builder will never send this backward command).

 22 - Delete Zone. This backward command will delete Zone with index given by Id. After deleting the Zone scene editor should send normal commands to delete all tracks, and send them again to ensure the Zone indexes are consistent between Builder and the scene editor. It is not working yet in version 0.08 (Builder will never send this backward command).

 23 - New Zone. This backward command will create a new Zone with index equal to the largest Zone index in the scene plus one. Builder will send only coordinates of one corner of the Zone (x1, y1 and z1 only). Scene editor should fill the remaining coordinates with default values. Scene editor should send the new Zone's parameters back to Builder (command 21 - Set Zone). It is not working yet in version 0.08 (Builder will never send this backward command).

 24 - Clone Zone (all parameters). This backward command will clone existing Zone with index equal to given Id parameter. The new Zone will have the Id of the largest Zone index in the scene plus one. It is not working yet in version 0.08 (Builder will never send this backward command).

 29 - New Zone (all parameters). This backward command will create a new Zone with index equal to the largest Zone index in the scene plus one. Builder will send all cordinates (x1, y1, z1, x2, y2, z2) for the new Zone. Scene Editor should send the new Zone's parameters back to Builder (command 21 - Set Zone). It is not working yet in version 0.08 (Builder will never send this backward command).

 30 - Set Actor coordinates. This backward command will move Actor with index specified by Id to new coordinates specified by [x1, y1, z1].

 31 - Select Actor. This backward command will indicate that Actor with index specified by Id has just been selected. The scene editor can react to this by highlighting that Actor, or by showing the Actor's parameters.

 32 - Delete Actor. This backward command will delete Actor with index given by Id. After deleting the Actor scene editor should send normal commands to delete all tracks, and send them again to ensure the Actor indexes are consistent between Builder and the scene editor.

 33 - New Actor. This backward command will create a new Actor with index equal to the largest Actor index in the scene plus one. Scene editor should send the new Actor's parameters back to Builder (command 31 - Set Actor).

 34 - Clone Actor. This backward command will clone existing Actor with index equal to given Id parameter. The new Actor will have the Id of the largest Actor index in the scene plus one.
 

 Backward command return values:
---------------------------------

 Scene editor should return one of the following values:

    0 - Error: Unknown error.
    1 - Error: Invalid id. Object with the specified Id does not exist.
   10 - Error: Invalid Backward Command. There is no Backward Command with the specified Backward Command Id.
  100 - Backward Command OK.
 1000 - Test OK. Return value for communication test Backward Command (01).